package org.molamil.acto.types {	
	import org.molamil.acto.core.parsers.ParserError;	
	
	/**
	 * Type parser expecting the value passed when <code>parse()</code> to be 
	 * "Number compatible". These values can e.g. be "100", "-0.5", "0xFF0000", etc.
	 * 
	 * <p>Note that unlike the <code>Number()</code> casting <code>parse()</code> 
	 * will fail if <code>value</code> is empty.</p>
	 * 
	 * @example The following code will parse "0.5" into <code>0.5</code>
	 * and will trace "HOLLY COW, I parsed a Number!!!":
	 * <listing version="3.0" >
	 * var parser:AbstractTypeParser = new NumberTypeParser();
	 * var n:Number = parser.parse("0.5");
	 * if (n == 0.5)
	 *    trace("HOLLY COW, I parsed a Number!!!");
	 * </listing>
	 * 
	 * @author Jorge Hernandez
	 */
	public class NumberTypeParser extends AbstractTypeParser {
		
		
		// CONSTANTS
		
		/**
		 * @inheritDoc
		 */
		public static const PRIORITY:uint = 400;
		
		/**
		 * @inheritDoc
		 */
		public static const TYPE:Class = Number;
		
		
		// PROTECTED METHODS
		
		/**
		 * Returns the numeric representation of the passed value, or throws
		 * an <code>Error</code> if value does not contain any representation 
		 * that can be parsed into a <code>Number</code>
		 * 
		 * <p>Note that unlike the <code>Number()</code> casting this method 
		 * will fail if value is empty.</p>
		 * 
		 * <p>The following strings will parse into a Number</p>
		 * <ul>
		 * 	<li>"100" will parse into <code>100</code></li>
		 * 	<li>"1" will parse into <code>1</code></li>
		 * 	<li>"0.75" will parse into <code>0.75</code></li>
		 * 	<li>"0x100" will parse into <code>256</code></li>
		 * 	<li>"-25.75" will parse into <code>-25.75</code></li>
		 * 	<li>"Infinity" will parse into <code>Infinity</code></li>
		 * </ul>
		 * 
		 * @param value <code>String</code> value to test
		 * @return <code>Number</code> representation of the value passed
		 * @throws org.molamil.acto.core.errors.ParserError The value can't
		 * 	be converted to a <code>Number</code>
		 */
		override protected function doParse(value:String):* {
			
			if (value == null)
				throw new ParserError("ERROR: value is null and cannot be parsed " +
					"into a Number");
			
			if (value == "")
				throw new ParserError("ERROR: '" + value + "' cannot be parsed " +
					"into a Number (value is empty)");
			
			var n:Number = Number(value);
			
			if (!isNaN(n)) {
				return n;
			} else {
				throw new ParserError("ERROR: '" + value + "' cannot be parsed " +
					"into a Number");
			}
			
		}
		
		
	}
	
}
